

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="Description" content="scikit-learn: machine learning in Python">

  
  <title>Compare the effect of different scalers on data with outliers &mdash; scikit-learn 0.22 documentation</title>
  
  <link rel="canonical" href="http://scikit-learn.org/stable/auto_examples/preprocessing/plot_all_scaling.html" />

  
  <link rel="shortcut icon" href="../../_static/favicon.ico"/>
  

  <link rel="stylesheet" href="../../_static/css/vendor/bootstrap.min.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/gallery.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script> 
</head>
<body>
<nav id="navbar" class="sk-docs-navbar navbar navbar-expand-md navbar-light bg-light py-0">
  <div class="container-fluid sk-docs-container px-0">
      <a class="navbar-brand py-0" href="../../index.html">
        <img
          class="sk-brand-img"
          src="../../_static/scikit-learn-logo-small.png"
          alt="logo"/>
      </a>
    <button
      id="sk-navbar-toggler"
      class="navbar-toggler"
      type="button"
      data-toggle="collapse"
      data-target="#navbarSupportedContent"
      aria-controls="navbarSupportedContent"
      aria-expanded="false"
      aria-label="Toggle navigation"
    >
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="sk-navbar-collapse collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item">
          <a class="sk-nav-link nav-link" href="../../install.html">Install</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link" href="../../user_guide.html">User Guide</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link" href="../../modules/classes.html">API</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link" href="../index.html">Examples</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../getting_started.html">Getting Started</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../tutorial/index.html">Tutorial</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../glossary.html">Glossary</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../developers/index.html">Development</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../faq.html">FAQ</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../related_projects.html">Related packages</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../roadmap.html">Roadmap</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="../../about.html">About us</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="https://github.com/scikit-learn/scikit-learn">GitHub</a>
        </li>
        <li class="nav-item">
          <a class="sk-nav-link nav-link nav-more-item-mobile-items" href="https://scikit-learn.org/dev/versions.html">Other Versions</a>
        </li>
        <li class="nav-item dropdown nav-more-item-dropdown">
          <a class="sk-nav-link nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">More</a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
              <a class="sk-nav-dropdown-item dropdown-item" href="../../getting_started.html">Getting Started</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../tutorial/index.html">Tutorial</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../glossary.html">Glossary</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../developers/index.html">Development</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../faq.html">FAQ</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../related_projects.html">Related packages</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../roadmap.html">Roadmap</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="../../about.html">About us</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="https://github.com/scikit-learn/scikit-learn">GitHub</a>
              <a class="sk-nav-dropdown-item dropdown-item" href="https://scikit-learn.org/dev/versions.html">Other Versions</a>
          </div>
        </li>
      </ul>
      <div id="searchbox" role="search">
          <div class="searchformwrapper">
          <form class="search" action="../../search.html" method="get">
            <input class="sk-search-text-input" type="text" name="q" aria-labelledby="searchlabel" />
            <input class="sk-search-text-btn" type="submit" value="Go" />
          </form>
          </div>
      </div>
    </div>
  </div>
</nav>
<div class="d-flex" id="sk-doc-wrapper">
    <input type="checkbox" name="sk-toggle-checkbox" id="sk-toggle-checkbox">
    <label id="sk-sidemenu-toggle" class="sk-btn-toggle-toc btn sk-btn-primary" for="sk-toggle-checkbox">Toggle Menu</label>
    <div id="sk-sidebar-wrapper" class="border-right">
      <div class="sk-sidebar-toc-wrapper">
        <div class="sk-sidebar-toc-logo">
          <a href="../../index.html">
            <img
              class="sk-brand-img"
              src="../../_static/scikit-learn-logo-small.png"
              alt="logo"/>
          </a>
        </div>
        <div class="btn-group w-100 mb-2" role="group" aria-label="rellinks">
            <a href="plot_discretization_classification.html" role="button" class="btn sk-btn-rellink py-1" sk-rellink-tooltip="Feature discretization">Prev</a><a href="../index.html" role="button" class="btn sk-btn-rellink py-1" sk-rellink-tooltip="Examples">Up</a>
            <a href="../release_highlights/plot_release_highlights_0_22_0.html" role="button" class="btn sk-btn-rellink py-1" sk-rellink-tooltip="Release Highlights for scikit-learn 0.22">Next</a>
        </div>
        <div class="alert alert-danger p-1 mb-2" role="alert">
          <p class="text-center mb-0">
          <strong>scikit-learn 0.22</strong><br/>
          <a href="http://scikit-learn.org/dev/versions.html">Other versions</a>
          </p>
        </div>
        <div class="alert alert-warning p-1 mb-2" role="alert">
          <p class="text-center mb-0">
            Please <a class="font-weight-bold" href="../../about.html#citing-scikit-learn"><string>cite us</string></a> if you use the software.
          </p>
        </div>
          <div class="sk-sidebar-toc">
            <ul>
<li><a class="reference internal" href="#">Compare the effect of different scalers on data with outliers</a><ul>
<li><a class="reference internal" href="#original-data">Original data</a></li>
<li><a class="reference internal" href="#standardscaler">StandardScaler</a></li>
<li><a class="reference internal" href="#minmaxscaler">MinMaxScaler</a></li>
<li><a class="reference internal" href="#maxabsscaler">MaxAbsScaler</a></li>
<li><a class="reference internal" href="#robustscaler">RobustScaler</a></li>
<li><a class="reference internal" href="#powertransformer">PowerTransformer</a></li>
<li><a class="reference internal" href="#quantiletransformer-gaussian-output">QuantileTransformer (Gaussian output)</a></li>
<li><a class="reference internal" href="#quantiletransformer-uniform-output">QuantileTransformer (uniform output)</a></li>
<li><a class="reference internal" href="#normalizer">Normalizer</a></li>
</ul>
</li>
</ul>

          </div>
      </div>
    </div>
    <div id="sk-page-content-wrapper">
      <div class="sk-page-content container-fluid body px-md-3" role="main">
        
  <div class="sphx-glr-download-link-note admonition note">
<p class="admonition-title">Note</p>
<p>Click <a class="reference internal" href="#sphx-glr-download-auto-examples-preprocessing-plot-all-scaling-py"><span class="std std-ref">here</span></a> to download the full example code or to run this example in your browser via Binder</p>
</div>
<div class="sphx-glr-example-title section" id="compare-the-effect-of-different-scalers-on-data-with-outliers">
<span id="sphx-glr-auto-examples-preprocessing-plot-all-scaling-py"></span><h1>Compare the effect of different scalers on data with outliers<a class="headerlink" href="#compare-the-effect-of-different-scalers-on-data-with-outliers" title="Permalink to this headline">¶</a></h1>
<p>Feature 0 (median income in a block) and feature 5 (number of households) of
the <a class="reference external" href="https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html">California housing dataset</a> have very
different scales and contain some very large outliers. These two
characteristics lead to difficulties to visualize the data and, more
importantly, they can degrade the predictive performance of many machine
learning algorithms. Unscaled data can also slow down or even prevent the
convergence of many gradient-based estimators.</p>
<p>Indeed many estimators are designed with the assumption that each feature takes
values close to zero or more importantly that all features vary on comparable
scales. In particular, metric-based and gradient-based estimators often assume
approximately standardized data (centered features with unit variances). A
notable exception are decision tree-based estimators that are robust to
arbitrary scaling of the data.</p>
<p>This example uses different scalers, transformers, and normalizers to bring the
data within a pre-defined range.</p>
<p>Scalers are linear (or more precisely affine) transformers and differ from each
other in the way to estimate the parameters used to shift and scale each
feature.</p>
<p><code class="docutils literal notranslate"><span class="pre">QuantileTransformer</span></code> provides non-linear transformations in which distances
between marginal outliers and inliers are shrunk. <code class="docutils literal notranslate"><span class="pre">PowerTransformer</span></code> provides
non-linear transformations in which data is mapped to a normal distribution to
stabilize variance and minimize skewness.</p>
<p>Unlike the previous transformations, normalization refers to a per sample
transformation instead of a per feature transformation.</p>
<p>The following code is a bit verbose, feel free to jump directly to the analysis
of the <a class="reference internal" href="#results">results</a>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Author:  Raghav RV &lt;rvraghav93@gmail.com&gt;</span>
<span class="c1">#          Guillaume Lemaitre &lt;g.lemaitre58@gmail.com&gt;</span>
<span class="c1">#          Thomas Unterthiner</span>
<span class="c1"># License: BSD 3 clause</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="kn">import</span> <span class="nn">matplotlib</span> <span class="k">as</span> <span class="nn">mpl</span>
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">cm</span>

<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">MinMaxScaler</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">minmax_scale</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">MaxAbsScaler</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">StandardScaler</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">RobustScaler</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">Normalizer</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">QuantileTransformer</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">PowerTransformer</span>

<span class="kn">from</span> <span class="nn">sklearn.datasets</span> <span class="kn">import</span> <span class="n">fetch_california_housing</span>

<span class="nb">print</span><span class="p">(</span><span class="vm">__doc__</span><span class="p">)</span>

<span class="n">dataset</span> <span class="o">=</span> <span class="n">fetch_california_housing</span><span class="p">()</span>
<span class="n">X_full</span><span class="p">,</span> <span class="n">y_full</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">dataset</span><span class="o">.</span><span class="n">target</span>

<span class="c1"># Take only 2 features to make visualization easier</span>
<span class="c1"># Feature of 0 has a long tail distribution.</span>
<span class="c1"># Feature 5 has a few but very large outliers.</span>

<span class="n">X</span> <span class="o">=</span> <span class="n">X_full</span><span class="p">[:,</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">5</span><span class="p">]]</span>

<span class="n">distributions</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">(</span><span class="s1">&#39;Unscaled data&#39;</span><span class="p">,</span> <span class="n">X</span><span class="p">),</span>
    <span class="p">(</span><span class="s1">&#39;Data after standard scaling&#39;</span><span class="p">,</span>
        <span class="n">StandardScaler</span><span class="p">()</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after min-max scaling&#39;</span><span class="p">,</span>
        <span class="n">MinMaxScaler</span><span class="p">()</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after max-abs scaling&#39;</span><span class="p">,</span>
        <span class="n">MaxAbsScaler</span><span class="p">()</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after robust scaling&#39;</span><span class="p">,</span>
        <span class="n">RobustScaler</span><span class="p">(</span><span class="n">quantile_range</span><span class="o">=</span><span class="p">(</span><span class="mi">25</span><span class="p">,</span> <span class="mi">75</span><span class="p">))</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after power transformation (Yeo-Johnson)&#39;</span><span class="p">,</span>
     <span class="n">PowerTransformer</span><span class="p">(</span><span class="n">method</span><span class="o">=</span><span class="s1">&#39;yeo-johnson&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after power transformation (Box-Cox)&#39;</span><span class="p">,</span>
     <span class="n">PowerTransformer</span><span class="p">(</span><span class="n">method</span><span class="o">=</span><span class="s1">&#39;box-cox&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after quantile transformation (gaussian pdf)&#39;</span><span class="p">,</span>
        <span class="n">QuantileTransformer</span><span class="p">(</span><span class="n">output_distribution</span><span class="o">=</span><span class="s1">&#39;normal&#39;</span><span class="p">)</span>
        <span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after quantile transformation (uniform pdf)&#39;</span><span class="p">,</span>
        <span class="n">QuantileTransformer</span><span class="p">(</span><span class="n">output_distribution</span><span class="o">=</span><span class="s1">&#39;uniform&#39;</span><span class="p">)</span>
        <span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
    <span class="p">(</span><span class="s1">&#39;Data after sample-wise L2 normalizing&#39;</span><span class="p">,</span>
        <span class="n">Normalizer</span><span class="p">()</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)),</span>
<span class="p">]</span>

<span class="c1"># scale the output between 0 and 1 for the colorbar</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">minmax_scale</span><span class="p">(</span><span class="n">y_full</span><span class="p">)</span>

<span class="c1"># plasma does not exist in matplotlib &lt; 1.5</span>
<span class="n">cmap</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">cm</span><span class="p">,</span> <span class="s1">&#39;plasma_r&#39;</span><span class="p">,</span> <span class="n">cm</span><span class="o">.</span><span class="n">hot_r</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">create_axes</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="mi">6</span><span class="p">)):</span>
    <span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="n">figsize</span><span class="p">)</span>
    <span class="n">fig</span><span class="o">.</span><span class="n">suptitle</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>

    <span class="c1"># define the axis for the first plot</span>
    <span class="n">left</span><span class="p">,</span> <span class="n">width</span> <span class="o">=</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.22</span>
    <span class="n">bottom</span><span class="p">,</span> <span class="n">height</span> <span class="o">=</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.7</span>
    <span class="n">bottom_h</span> <span class="o">=</span> <span class="n">height</span> <span class="o">+</span> <span class="mf">0.15</span>
    <span class="n">left_h</span> <span class="o">=</span> <span class="n">left</span> <span class="o">+</span> <span class="n">width</span> <span class="o">+</span> <span class="mf">0.02</span>

    <span class="n">rect_scatter</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="n">bottom</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">]</span>
    <span class="n">rect_histx</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="n">bottom_h</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">]</span>
    <span class="n">rect_histy</span> <span class="o">=</span> <span class="p">[</span><span class="n">left_h</span><span class="p">,</span> <span class="n">bottom</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">,</span> <span class="n">height</span><span class="p">]</span>

    <span class="n">ax_scatter</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_scatter</span><span class="p">)</span>
    <span class="n">ax_histx</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_histx</span><span class="p">)</span>
    <span class="n">ax_histy</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_histy</span><span class="p">)</span>

    <span class="c1"># define the axis for the zoomed-in plot</span>
    <span class="n">left</span> <span class="o">=</span> <span class="n">width</span> <span class="o">+</span> <span class="n">left</span> <span class="o">+</span> <span class="mf">0.2</span>
    <span class="n">left_h</span> <span class="o">=</span> <span class="n">left</span> <span class="o">+</span> <span class="n">width</span> <span class="o">+</span> <span class="mf">0.02</span>

    <span class="n">rect_scatter</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="n">bottom</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">]</span>
    <span class="n">rect_histx</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="n">bottom_h</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">]</span>
    <span class="n">rect_histy</span> <span class="o">=</span> <span class="p">[</span><span class="n">left_h</span><span class="p">,</span> <span class="n">bottom</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">,</span> <span class="n">height</span><span class="p">]</span>

    <span class="n">ax_scatter_zoom</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_scatter</span><span class="p">)</span>
    <span class="n">ax_histx_zoom</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_histx</span><span class="p">)</span>
    <span class="n">ax_histy_zoom</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_histy</span><span class="p">)</span>

    <span class="c1"># define the axis for the colorbar</span>
    <span class="n">left</span><span class="p">,</span> <span class="n">width</span> <span class="o">=</span> <span class="n">width</span> <span class="o">+</span> <span class="n">left</span> <span class="o">+</span> <span class="mf">0.13</span><span class="p">,</span> <span class="mf">0.01</span>

    <span class="n">rect_colorbar</span> <span class="o">=</span> <span class="p">[</span><span class="n">left</span><span class="p">,</span> <span class="n">bottom</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">]</span>
    <span class="n">ax_colorbar</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">(</span><span class="n">rect_colorbar</span><span class="p">)</span>

    <span class="k">return</span> <span class="p">((</span><span class="n">ax_scatter</span><span class="p">,</span> <span class="n">ax_histy</span><span class="p">,</span> <span class="n">ax_histx</span><span class="p">),</span>
            <span class="p">(</span><span class="n">ax_scatter_zoom</span><span class="p">,</span> <span class="n">ax_histy_zoom</span><span class="p">,</span> <span class="n">ax_histx_zoom</span><span class="p">),</span>
            <span class="n">ax_colorbar</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">plot_distribution</span><span class="p">(</span><span class="n">axes</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">hist_nbins</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
                      <span class="n">x0_label</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">x1_label</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">):</span>
    <span class="n">ax</span><span class="p">,</span> <span class="n">hist_X1</span><span class="p">,</span> <span class="n">hist_X0</span> <span class="o">=</span> <span class="n">axes</span>

    <span class="n">ax</span><span class="o">.</span><span class="n">set_title</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="n">x0_label</span><span class="p">)</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="n">x1_label</span><span class="p">)</span>

    <span class="c1"># The scatter plot</span>
    <span class="n">colors</span> <span class="o">=</span> <span class="n">cmap</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">X</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">marker</span><span class="o">=</span><span class="s1">&#39;o&#39;</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="n">colors</span><span class="p">)</span>

    <span class="c1"># Removing the top and the right spine for aesthetics</span>
    <span class="c1"># make nice axis layout</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">spines</span><span class="p">[</span><span class="s1">&#39;top&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">set_visible</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">spines</span><span class="p">[</span><span class="s1">&#39;right&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">set_visible</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">get_xaxis</span><span class="p">()</span><span class="o">.</span><span class="n">tick_bottom</span><span class="p">()</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">get_yaxis</span><span class="p">()</span><span class="o">.</span><span class="n">tick_left</span><span class="p">()</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">spines</span><span class="p">[</span><span class="s1">&#39;left&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">set_position</span><span class="p">((</span><span class="s1">&#39;outward&#39;</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>
    <span class="n">ax</span><span class="o">.</span><span class="n">spines</span><span class="p">[</span><span class="s1">&#39;bottom&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">set_position</span><span class="p">((</span><span class="s1">&#39;outward&#39;</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>

    <span class="c1"># Histogram for axis X1 (feature 5)</span>
    <span class="n">hist_X1</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="n">ax</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">())</span>
    <span class="n">hist_X1</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">bins</span><span class="o">=</span><span class="n">hist_nbins</span><span class="p">,</span> <span class="n">orientation</span><span class="o">=</span><span class="s1">&#39;horizontal&#39;</span><span class="p">,</span>
                 <span class="n">color</span><span class="o">=</span><span class="s1">&#39;grey&#39;</span><span class="p">,</span> <span class="n">ec</span><span class="o">=</span><span class="s1">&#39;grey&#39;</span><span class="p">)</span>
    <span class="n">hist_X1</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s1">&#39;off&#39;</span><span class="p">)</span>

    <span class="c1"># Histogram for axis X0 (feature 0)</span>
    <span class="n">hist_X0</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">ax</span><span class="o">.</span><span class="n">get_xlim</span><span class="p">())</span>
    <span class="n">hist_X0</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">bins</span><span class="o">=</span><span class="n">hist_nbins</span><span class="p">,</span> <span class="n">orientation</span><span class="o">=</span><span class="s1">&#39;vertical&#39;</span><span class="p">,</span>
                 <span class="n">color</span><span class="o">=</span><span class="s1">&#39;grey&#39;</span><span class="p">,</span> <span class="n">ec</span><span class="o">=</span><span class="s1">&#39;grey&#39;</span><span class="p">)</span>
    <span class="n">hist_X0</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s1">&#39;off&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Two plots will be shown for each scaler/normalizer/transformer. The left
figure will show a scatter plot of the full data set while the right figure
will exclude the extreme values considering only 99 % of the data set,
excluding marginal outliers. In addition, the marginal distributions for each
feature will be shown on the side of the scatter plot.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">make_plot</span><span class="p">(</span><span class="n">item_idx</span><span class="p">):</span>
    <span class="n">title</span><span class="p">,</span> <span class="n">X</span> <span class="o">=</span> <span class="n">distributions</span><span class="p">[</span><span class="n">item_idx</span><span class="p">]</span>
    <span class="n">ax_zoom_out</span><span class="p">,</span> <span class="n">ax_zoom_in</span><span class="p">,</span> <span class="n">ax_colorbar</span> <span class="o">=</span> <span class="n">create_axes</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
    <span class="n">axarr</span> <span class="o">=</span> <span class="p">(</span><span class="n">ax_zoom_out</span><span class="p">,</span> <span class="n">ax_zoom_in</span><span class="p">)</span>
    <span class="n">plot_distribution</span><span class="p">(</span><span class="n">axarr</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">hist_nbins</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span>
                      <span class="n">x0_label</span><span class="o">=</span><span class="s2">&quot;Median Income&quot;</span><span class="p">,</span>
                      <span class="n">x1_label</span><span class="o">=</span><span class="s2">&quot;Number of households&quot;</span><span class="p">,</span>
                      <span class="n">title</span><span class="o">=</span><span class="s2">&quot;Full data&quot;</span><span class="p">)</span>

    <span class="c1"># zoom-in</span>
    <span class="n">zoom_in_percentile_range</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">99</span><span class="p">)</span>
    <span class="n">cutoffs_X0</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">percentile</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">zoom_in_percentile_range</span><span class="p">)</span>
    <span class="n">cutoffs_X1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">percentile</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">zoom_in_percentile_range</span><span class="p">)</span>

    <span class="n">non_outliers_mask</span> <span class="o">=</span> <span class="p">(</span>
        <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">X</span> <span class="o">&gt;</span> <span class="p">[</span><span class="n">cutoffs_X0</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">cutoffs_X1</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span>
        <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">X</span> <span class="o">&lt;</span> <span class="p">[</span><span class="n">cutoffs_X0</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">cutoffs_X1</span><span class="p">[</span><span class="mi">1</span><span class="p">]],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
    <span class="n">plot_distribution</span><span class="p">(</span><span class="n">axarr</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">X</span><span class="p">[</span><span class="n">non_outliers_mask</span><span class="p">],</span> <span class="n">y</span><span class="p">[</span><span class="n">non_outliers_mask</span><span class="p">],</span>
                      <span class="n">hist_nbins</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
                      <span class="n">x0_label</span><span class="o">=</span><span class="s2">&quot;Median Income&quot;</span><span class="p">,</span>
                      <span class="n">x1_label</span><span class="o">=</span><span class="s2">&quot;Number of households&quot;</span><span class="p">,</span>
                      <span class="n">title</span><span class="o">=</span><span class="s2">&quot;Zoom-in&quot;</span><span class="p">)</span>

    <span class="n">norm</span> <span class="o">=</span> <span class="n">mpl</span><span class="o">.</span><span class="n">colors</span><span class="o">.</span><span class="n">Normalize</span><span class="p">(</span><span class="n">y_full</span><span class="o">.</span><span class="n">min</span><span class="p">(),</span> <span class="n">y_full</span><span class="o">.</span><span class="n">max</span><span class="p">())</span>
    <span class="n">mpl</span><span class="o">.</span><span class="n">colorbar</span><span class="o">.</span><span class="n">ColorbarBase</span><span class="p">(</span><span class="n">ax_colorbar</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="n">cmap</span><span class="p">,</span>
                              <span class="n">norm</span><span class="o">=</span><span class="n">norm</span><span class="p">,</span> <span class="n">orientation</span><span class="o">=</span><span class="s1">&#39;vertical&#39;</span><span class="p">,</span>
                              <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Color mapping for values of y&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="original-data">
<span id="results"></span><h2>Original data<a class="headerlink" href="#original-data" title="Permalink to this headline">¶</a></h2>
<p>Each transformation is plotted showing two transformed features, with the
left plot showing the entire dataset, and the right zoomed-in to show the
dataset without the marginal outliers. A large majority of the samples are
compacted to a specific range, [0, 10] for the median income and [0, 6] for
the number of households. Note that there are some marginal outliers (some
blocks have more than 1200 households). Therefore, a specific pre-processing
can be very beneficial depending of the application. In the following, we
present some insights and behaviors of those pre-processing methods in the
presence of marginal outliers.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="standardscaler">
<h2>StandardScaler<a class="headerlink" href="#standardscaler" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">StandardScaler</span></code> removes the mean and scales the data to unit variance.
However, the outliers have an influence when computing the empirical mean and
standard deviation which shrink the range of the feature values as shown in
the left figure below. Note in particular that because the outliers on each
feature have different magnitudes, the spread of the transformed data on
each feature is very different: most of the data lie in the [-2, 4] range for
the transformed median income feature while the same data is squeezed in the
smaller [-0.2, 0.2] range for the transformed number of households.</p>
<p><code class="docutils literal notranslate"><span class="pre">StandardScaler</span></code> therefore cannot guarantee balanced feature scales in the
presence of outliers.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="minmaxscaler">
<h2>MinMaxScaler<a class="headerlink" href="#minmaxscaler" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">MinMaxScaler</span></code> rescales the data set such that all feature values are in
the range [0, 1] as shown in the right panel below. However, this scaling
compress all inliers in the narrow range [0, 0.005] for the transformed
number of households.</p>
<p>As <code class="docutils literal notranslate"><span class="pre">StandardScaler</span></code>, <code class="docutils literal notranslate"><span class="pre">MinMaxScaler</span></code> is very sensitive to the presence of
outliers.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="maxabsscaler">
<h2>MaxAbsScaler<a class="headerlink" href="#maxabsscaler" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">MaxAbsScaler</span></code> differs from the previous scaler such that the absolute
values are mapped in the range [0, 1]. On positive only data, this scaler
behaves similarly to <code class="docutils literal notranslate"><span class="pre">MinMaxScaler</span></code> and therefore also suffers from the
presence of large outliers.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="robustscaler">
<h2>RobustScaler<a class="headerlink" href="#robustscaler" title="Permalink to this headline">¶</a></h2>
<p>Unlike the previous scalers, the centering and scaling statistics of this
scaler are based on percentiles and are therefore not influenced by a few
number of very large marginal outliers. Consequently, the resulting range of
the transformed feature values is larger than for the previous scalers and,
more importantly, are approximately similar: for both features most of the
transformed values lie in a [-2, 3] range as seen in the zoomed-in figure.
Note that the outliers themselves are still present in the transformed data.
If a separate outlier clipping is desirable, a non-linear transformation is
required (see below).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="powertransformer">
<h2>PowerTransformer<a class="headerlink" href="#powertransformer" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">PowerTransformer</span></code> applies a power transformation to each feature to make
the data more Gaussian-like. Currently, <code class="docutils literal notranslate"><span class="pre">PowerTransformer</span></code> implements the
Yeo-Johnson and Box-Cox transforms. The power transform finds the optimal
scaling factor to stabilize variance and mimimize skewness through maximum
likelihood estimation. By default, <code class="docutils literal notranslate"><span class="pre">PowerTransformer</span></code> also applies
zero-mean, unit variance normalization to the transformed output. Note that
Box-Cox can only be applied to strictly positive data. Income and number of
households happen to be strictly positive, but if negative values are present
the Yeo-Johnson transformed is to be preferred.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">make_plot</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="quantiletransformer-gaussian-output">
<h2>QuantileTransformer (Gaussian output)<a class="headerlink" href="#quantiletransformer-gaussian-output" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">QuantileTransformer</span></code> has an additional <code class="docutils literal notranslate"><span class="pre">output_distribution</span></code> parameter
allowing to match a Gaussian distribution instead of a uniform distribution.
Note that this non-parametetric transformer introduces saturation artifacts
for extreme values.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="quantiletransformer-uniform-output">
<h2>QuantileTransformer (uniform output)<a class="headerlink" href="#quantiletransformer-uniform-output" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">QuantileTransformer</span></code> applies a non-linear transformation such that the
probability density function of each feature will be mapped to a uniform
distribution. In this case, all the data will be mapped in the range [0, 1],
even the outliers which cannot be distinguished anymore from the inliers.</p>
<p>As <code class="docutils literal notranslate"><span class="pre">RobustScaler</span></code>, <code class="docutils literal notranslate"><span class="pre">QuantileTransformer</span></code> is robust to outliers in the
sense that adding or removing outliers in the training set will yield
approximately the same transformation on held out data. But contrary to
<code class="docutils literal notranslate"><span class="pre">RobustScaler</span></code>, <code class="docutils literal notranslate"><span class="pre">QuantileTransformer</span></code> will also automatically collapse
any outlier by setting them to the a priori defined range boundaries (0 and
1).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="normalizer">
<h2>Normalizer<a class="headerlink" href="#normalizer" title="Permalink to this headline">¶</a></h2>
<p>The <code class="docutils literal notranslate"><span class="pre">Normalizer</span></code> rescales the vector for each sample to have unit norm,
independently of the distribution of the samples. It can be seen on both
figures below where all samples are mapped onto the unit circle. In our
example the two selected features have only positive values; therefore the
transformed data only lie in the positive quadrant. This would not be the
case if some original features had a mix of positive and negative values.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_plot</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>

<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</pre></div>
</div>
<p class="sphx-glr-timing"><strong>Total running time of the script:</strong> ( 0 minutes  0.000 seconds)</p>
<div class="sphx-glr-footer class sphx-glr-footer-example docutils container" id="sphx-glr-download-auto-examples-preprocessing-plot-all-scaling-py">
<div class="binder-badge docutils container">
<a class="reference external image-reference" href="https://mybinder.org/v2/gh/scikit-learn/scikit-learn/0.22.X?urlpath=lab/tree/notebooks/auto_examples/preprocessing/plot_all_scaling.ipynb"><img alt="https://mybinder.org/badge_logo.svg" src="https://mybinder.org/badge_logo.svg" width="150px" /></a>
</div>
<div class="sphx-glr-download docutils container">
<p><a class="reference download internal" download="" href="../../_downloads/7b9a2ffae80e32616abc304f8da9eea1/plot_all_scaling.py"><code class="xref download docutils literal notranslate"><span class="pre">Download</span> <span class="pre">Python</span> <span class="pre">source</span> <span class="pre">code:</span> <span class="pre">plot_all_scaling.py</span></code></a></p>
</div>
<div class="sphx-glr-download docutils container">
<p><a class="reference download internal" download="" href="../../_downloads/55bbb8e1d2c01d0be17449e0d720476e/plot_all_scaling.ipynb"><code class="xref download docutils literal notranslate"><span class="pre">Download</span> <span class="pre">Jupyter</span> <span class="pre">notebook:</span> <span class="pre">plot_all_scaling.ipynb</span></code></a></p>
</div>
</div>
<p class="sphx-glr-signature"><a class="reference external" href="https://sphinx-gallery.github.io">Gallery generated by Sphinx-Gallery</a></p>
</div>
</div>


      </div>
    <div class="container">
      <footer class="sk-content-footer">
            &copy; 2007 - 2019, scikit-learn developers (BSD License).
          <a href="../../_sources/auto_examples/preprocessing/plot_all_scaling.rst.txt" rel="nofollow">Show this page source</a>
      </footer>
    </div>
  </div>
</div>
<script src="../../_static/js/vendor/bootstrap.min.js"></script>

<script>
    window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
    ga('create', 'UA-22606712-2', 'auto');
    ga('set', 'anonymizeIp', true);
    ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>


<script>
$(document).ready(function() {
    /* Add a [>>>] button on the top-right corner of code samples to hide
     * the >>> and ... prompts and the output and thus make the code
     * copyable. */
    var div = $('.highlight-python .highlight,' +
                '.highlight-python3 .highlight,' +
                '.highlight-pycon .highlight,' +
		'.highlight-default .highlight')
    var pre = div.find('pre');

    // get the styles from the current theme
    pre.parent().parent().css('position', 'relative');
    var hide_text = 'Hide prompts and outputs';
    var show_text = 'Show prompts and outputs';

    // create and add the button to all the code blocks that contain >>>
    div.each(function(index) {
        var jthis = $(this);
        if (jthis.find('.gp').length > 0) {
            var button = $('<span class="copybutton">&gt;&gt;&gt;</span>');
            button.attr('title', hide_text);
            button.data('hidden', 'false');
            jthis.prepend(button);
        }
        // tracebacks (.gt) contain bare text elements that need to be
        // wrapped in a span to work with .nextUntil() (see later)
        jthis.find('pre:has(.gt)').contents().filter(function() {
            return ((this.nodeType == 3) && (this.data.trim().length > 0));
        }).wrap('<span>');
    });

    // define the behavior of the button when it's clicked
    $('.copybutton').click(function(e){
        e.preventDefault();
        var button = $(this);
        if (button.data('hidden') === 'false') {
            // hide the code output
            button.parent().find('.go, .gp, .gt').hide();
            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
            button.css('text-decoration', 'line-through');
            button.attr('title', show_text);
            button.data('hidden', 'true');
        } else {
            // show the code output
            button.parent().find('.go, .gp, .gt').show();
            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
            button.css('text-decoration', 'none');
            button.attr('title', hide_text);
            button.data('hidden', 'false');
        }
    });

	/*** Add permalink buttons next to glossary terms ***/
	$('dl.glossary > dt[id]').append(function() {
		return ('<a class="headerlink" href="#' +
			    this.getAttribute('id') +
			    '" title="Permalink to this term">¶</a>');
	});
  /*** Hide navbar when scrolling down ***/
  // Returns true when headerlink target matches hash in url
  (function() {
    hashTargetOnTop = function() {
        var hash = window.location.hash;
        if ( hash.length < 2 ) { return false; }

        var target = document.getElementById( hash.slice(1) );
        if ( target === null ) { return false; }

        var top = target.getBoundingClientRect().top;
        return (top < 2) && (top > -2);
    };

    // Hide navbar on load if hash target is on top
    var navBar = document.getElementById("navbar");
    var navBarToggler = document.getElementById("sk-navbar-toggler");
    var navBarHeightHidden = "-" + navBar.getBoundingClientRect().height + "px";
    var $window = $(window);

    hideNavBar = function() {
        navBar.style.top = navBarHeightHidden;
    };

    showNavBar = function() {
        navBar.style.top = "0";
    }

    if (hashTargetOnTop()) {
        hideNavBar()
    }

    var prevScrollpos = window.pageYOffset;
    hideOnScroll = function(lastScrollTop) {
        if (($window.width() < 768) && (navBarToggler.getAttribute("aria-expanded") === 'true')) {
            return;
        }
        if (lastScrollTop > 2 && (prevScrollpos <= lastScrollTop) || hashTargetOnTop()){
            hideNavBar()
        } else {
            showNavBar()
        }
        prevScrollpos = lastScrollTop;
    };

    /*** high preformance scroll event listener***/
    var raf = window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame;
    var lastScrollTop = $window.scrollTop();

    if (raf) {
        loop();
    }

    function loop() {
        var scrollTop = $window.scrollTop();
        if (lastScrollTop === scrollTop) {
            raf(loop);
            return;
        } else {
            lastScrollTop = scrollTop;
            hideOnScroll(lastScrollTop);
            raf(loop);
        }
    }
  })();
});

</script>
    
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
    
</body>
</html>